--[[
@classmod Sled
]]

local Tile = require "tile"
local Map = require "map"
local Input = require "input"
local Layer = require "layer"
local seq = pl.seq
local tmap = pl.tablex.map
local timer = require "lib.timer"
local lume = require "lib.lume"

return pl.class {
	_name = "Sled",
	
	start = function (self)
		timer.after(1, function ()
			self.state = "map"
			self.w, self.h = w or self.config.tbl.width or 128, h or self.config.tbl.height or 128
			self.grid = require "grid"(self.tile_size, self.w, self.h)
			self.cursor = require "cursor"(self.tile_size, self.grid)
			self.gui = require "gui"(self.config)
			self.current_screen = require "mapeditor"(self.w, self.h, 4.5)
			if self.file then self:import_map (file)
			else self:make_map(nil, self.w, self.h) 
			end
		end)
	end,
	
	restart = function (self)
		self.state = "splash"
		self.config = require "config"()
		self.w, self.h = w or self.config.tbl.width or 128, h or self.config.tbl.height or 128
		Sled.maps = {}
		Sled.current_tile = nil
		Sled.tile_buffer = nil
		Sled.current_map = nil
		timer.after(.2, function () self:start() end)
	end,
	
	_init = function (self, ts, w, h, file)
		self.state = "splash"
		self.file = file
		self.config = require "config"()
		self.splash = require "splash"()
		self.tile_size = ts
		self.w, self.h = w or self.config.width or 128, h or self.config.height or 128
		local kb = require "config.keybindings"
		self.input = Input(kb)
		self.maps = {}
		timer.after(.2, function () self:start() end)
	end,
	
	update = function (self, dt)
		timer.update(dt)
		if self.state == "splash" then
		return
		end
		tmap(function (v)
			if v.update then
				v:update(dt)
			end
		end, {
			self.input,
			self.cursor,
			self.gui,
			self.current_map
			
		})
		
	end,
	
	quit = function (self)
		love.event.quit()
	end,
	
	draw = function (self)
		if self.state == "splash" then
			self.splash:draw()
		return
		end
		self.current_screen:draw({
			self.current_map,
			self.grid,
			self.cursor,
		})
		
		tmap(function (v)
			if v.draw then
				v:draw()
			end
		end, {
			self.gui,
		})
	end,
	
	get_map = function (self, map_name)
		return lume.match(self.maps, function (v)
				return v:get_name() == map_name
			end)
	end,
	
	switch_to_map = function (self, map_name)
		local map = self:get_map(map_name)
		self.current_layer = map.layers.tbl[1]
		self.current_map = map
		self.grid:resize(map.w, map.h)
		self.current_screen.w, self.current_screen.h = map.w, map.h
		self.current_screen:center(0, 0, map.w, map.h)
	end,
	
	make_map = function (self, _name, w, h)
		local name = _name or "untitled"
		local count = lume.count(self.maps, function (m)
			return name == m:get_name()
		end)
		if count > 0 then
			name = name .. "("..(count+1)..")"
		end
		local w = w or 16
		local h = h or 16
		local m = Map(name, w, h)
		table.insert(self.maps, m)
		self:switch_to_map (name)
		return m
	end,
	
	tile = function (self, x, y)
		return Tile(x, y)
	end,
	
	import_map = function (self, filename)
		local content, err = _lf.read(filename)
		if not content then return err end
		local mdata = pl.pretty.read(content)
		if not mdata then return "bad map format? couldn't read data" end
		local map = self:make_map(mdata.name, mdata.w, mdata.h)
		lume.each(mdata.markers, function (m)
			map:marker_add(m.name, m.x, m.y)
		end)
		lume.each(mdata.layers, function (l)
			map.layers:add_from_str (l.name, l.z, l.w, l.h, l.str)
		end)
		self:switch_to_map (map.name)
	end,
}
